package com.jadesoft.ciadapter.plugin.base;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletContext;
import javax.servlet.ServletRequest;

import org.apache.commons.lang.StringUtils;

import com.ufida.leaf.exception.BusinessException;


@SuppressWarnings("unchecked")
public class PluginManager {
	public static ServletContext context ;
	
	public static void addPlugin(String pluginType,String tag,PluginAction action,Object container){
		if (StringUtils.isBlank(tag) || action == null){
			return ;
		}
		
		container = container == null ? context : container ;
		
		Map<String,List<PluginAction>> plugins = null ;
		Object plgs = attribute(container,pluginType,null);
		plugins = plgs != null ? (Map<String,List<PluginAction>>)plgs : new HashMap<String,List<PluginAction>>();
		
		List<PluginAction> actionForTag = plugins.get(tag);
		actionForTag = actionForTag != null ? actionForTag : new ArrayList<PluginAction>();
		
		actionForTag.add(action);
		
		if (plugins.get(tag) == null){
			plugins.put(tag, actionForTag);
		}
		if (plgs==null){
			attribute(container,pluginType,plugins);
		}
	}

	public static void addAction(String tag,PluginAction action,Object container){
		addPlugin("plugins",tag,action,container);
	}
	private static Object attribute(Object obj,String key,Object value){
		Object result = null ;
		if ( value == null){
			try {
				Method method = obj.getClass().getDeclaredMethod("getAttribute", new Class[]{String.class});
				result = method.invoke(obj, key);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			return result ;
		} else {
			try {
				Method method = obj.getClass().getDeclaredMethod("setAttribute", new Class[]{String.class,Object.class});
				method.invoke(obj, key,value);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			return null ;
		}
	}
	public static void addAction(String tag,PluginAction action){
		addAction(tag, action,null);
	}
	public static String doAction(String tag,Object... args){
		String result = doActionFor(context,tag,args);
		if ( args.length>0 && args[0] instanceof ServletRequest){
			result += doActionFor(args[0],tag,args);
		}
		return result ;
	}
	private static String doActionFor(Object container,String tag,Object... args){
		
		Object plgs = attribute(container,"plugins",null);
		if (plgs == null || StringUtils.isBlank(tag) ){
			return "";
		}
		Map<String,List<PluginAction>> plugins = (Map<String,List<PluginAction>>)plgs;
		List<PluginAction> actionForTag = plugins.get(tag);
		if (actionForTag == null){
			return "" ;
		}
		StringBuffer result = new StringBuffer();
		for (PluginAction action : actionForTag){
			Object retObj = action.exec(args);
			if (retObj instanceof String){
				result.append((String)retObj);
			}
		}
		return result.toString();
	}
	
	public static void addFilter(String tag,PluginAction action,Object container){
		addPlugin("filters",tag,action,container);
	}
	public static Object doFilter(String tag,Object... args){
		Object container = null ;
		Object orignal = null;
		if ( args.length<2 || ! (args[0] instanceof ServletRequest)){
			throw new BusinessException("参数错误");
		}
		container = args[0];
		orignal = args[1];
		
		Object plgs = attribute(container,"filters",null);
		if (plgs == null || StringUtils.isBlank(tag) ){
			return orignal;
		}
		Map<String,List<PluginAction>> plugins = (Map<String,List<PluginAction>>)plgs;
		List<PluginAction> actionForTag = plugins.get(tag);
		if (actionForTag == null){
			return orignal ;
		}
		Object result = null;
		for (PluginAction action : actionForTag){
			result = action.exec(args);
			args[1] = result ;
		}
		return result;
	}
	
}
